//来自设备数据需要转为16进制显示
//按照设备号把来自传感器的数据存进数据库
//9901+设备id+modbus指令为查询指令，转发查询指令至相应设备,9901199179159791234001010300000002C40B
/*1234+设备id为注册包，统一格式1234+用户名+通讯密码4位+设备号，一共22位
格式：1234179159791234000001 */


const net = require('net')
const ToModbusCRC16 = require('./crc16.js')
const { DeviceDataModel ,ChildrenSlaversModel} = require('../models/models')



//创建webclient
const webclient = net.connect(15001);
//储存连接

webclient.on('connect', () => {
    console.log('web服务连接成功');
})
webclient.on('data', (data) => {
    console.log(data)
})

webclient.on('close', () => {
    console.log('web服务连接断开')
})

const server = net.createServer().listen(15000, () => console.log('开始监听15000'));
let RTU_pool = {}
let clientAddressPort = {}
server.on('connection', (c) => {
    // console.log(c.remoteAddress);
    c.on('data', (data) => {
        let hexData = data.toString('hex').toLowerCase();
        let norData = data.toString().toLowerCase();
        // console.log(norData);

        //如果长度为22且以1234开头,为注册包
        if (hexData.length == 22 && hexData.substr(0, 4) === '1234') {
            // console.log(hexData, norData, hexData.length, 'if');
            //保存write方法
            RTU_pool[hexData.substr(4)] = c;
            //建立地址端口与设备id的索引
            clientAddressPort[c.remoteAddress + c.remotePort] = hexData.substr(4);
            //发送设备上线通知
            webclient.write('sx' + hexData.substr(4))





        }
        //如果数据起始位为9901，则为查询数据,第5位开始的18位为设备id
        else if (norData.substr(0, 4) === '9901') {
            //如果设备在线则转发数据
            if (RTU_pool[norData.substr(4, 18)]) {
                RTU_pool[norData.substr(4, 18)].write(Buffer.from(norData.substr(22), 'hex'))
                // console.log(norData.substr(0, 4), norData.substr(4, 18), norData.substr(22), 'else if');
                //把查询指令存在与设备连接的modBusData中
                RTU_pool[norData.substr(4, 18)].modBusData = Buffer.from(norData.substr(22), 'hex');
                RTU_pool[norData.substr(4, 18)].deviceid = norData.substr(4, 18);





            }

        } else {
            //进行CRC校验
            if (ToModbusCRC16(hexData.substr(0, 14)) == hexData.substr(-4)) {
                //存进数据库
                DeviceDataModel.insertMany({
                    username:c.deviceid.substr(0,9),
                    deviceid: c.deviceid,
                    slaverIndex: hexData.substr(0, 2), //从机号 *01
                    createTime: Date.now(),
                    value: hexData.slice(4, -4)  //传感器数据 去掉前后四位数
                })


                //实时数据存入，前端渲染
                // ChildrenSlaversModel.updateOne({ 'deviceid': c.deviceid, 'slaver': hexData.substr(0, 2) }, {

                //     'value': hexData.slice(4, -4),
                //     'time': new Date().getTime(),
                //     'deviceid': c.deviceid,
                //     'slaver': hexData.substr(0, 2)
                // }, {
                //         upsert: true,
                //         multi: true
                //     }).catch(err => console.log(err))
                // console.log(hexData, ToModbusCRC16(hexData.substr(0, 14)), 3.1);


            } else {
                //校验失败重发
                if (c.modBusData) {
                    c.write(c.modBusData)
                    console.log('crc校验失败，已经重发查询指令')
                }
                
            }

        }

    })


    c.on('error', (err) => {
        if (RTU_pool[clientAddressPort[c.remoteAddress + c.remotePort]]) {
            //连接断开从RTU_poll移除设备
            delete RTU_pool[clientAddressPort[c.remoteAddress + c.remotePort]];
            delete clientAddressPort[c.remoteAddress + c.remotePort]
            //新建client连接WebSocket_Server
            webclient.write('xx' + clientAddressPort[c.remoteAddress + c.remotePort])
            c.destroy();
            // console.warn(err)
        }

    })

    c.on('close', () => {
        if (RTU_pool[clientAddressPort[c.remoteAddress + c.remotePort]]) {
            //连接断开从RTU_poll移除设备
            delete RTU_pool[clientAddressPort[c.remoteAddress + c.remotePort]];
            delete clientAddressPort[c.remoteAddress + c.remotePort]
            //新建client连接WebSocket_Server
            webclient.write('xx' + clientAddressPort[c.remoteAddress + c.remotePort])
        }

    })
})